Triggers হল একটি বিশেষ ধরনের স্টোরড প্রোগ্রাম যা একটি নির্দিষ্ট ইভেন্ট (যেমন ইনসার্ট, আপডেট বা ডিলিট) ঘটার পর স্বয়ংক্রিয়ভাবে কার্যকর হয়। PL/SQL-এ Triggers ব্যবহৃত হয় ডেটাবেস টেবিলের বা ভিউ-এর ওপর কোনো নির্দিষ্ট পরিবর্তন বা কর্মকাণ্ডের জন্য স্বয়ংক্রিয় প্রতিক্রিয়া তৈরি করার জন্য।
PL/SQL-এ ট্রিগারগুলি বিভিন্ন ইভেন্টের প্রতিক্রিয়া হিসেবে চলে, এবং এগুলি আপনার ডেটাবেসের ইন্টিগ্রিটি বজায় রাখতে, অডিটিং বা লগিং করতে, অথবা কোনো প্রক্রিয়া স্বয়ংক্রিয় করতে ব্যবহৃত হতে পারে।
PL/SQL Trigger এর গঠন:
PL/SQL ট্রিগার সাধারণত তিনটি অংশে বিভক্ত থাকে:
- ট্রিগার ইভেন্ট (Insert, Update, Delete)
- ট্রিগার টাইপ (BEFORE, AFTER, INSTEAD OF)
- ট্রিগার বডি (PL/SQL কোড যা কার্যকর হয়)
ট্রিগার টাইপ
PL/SQL-এ তিন ধরনের ট্রিগার ব্যবহৃত হয়:
- BEFORE Trigger:
- এই ট্রিগারটি ডেটাবেস অপারেশন (যেমন
INSERT,UPDATE, বাDELETE) কার্যকর হওয়ার আগে চলে। - এটি মূলত ডেটার বৈধতা যাচাই বা ডেটা প্রক্রিয়া করার জন্য ব্যবহৃত হয়।
- এই ট্রিগারটি ডেটাবেস অপারেশন (যেমন
- AFTER Trigger:
- এই ট্রিগারটি ডেটাবেস অপারেশন (যেমন
INSERT,UPDATE, বাDELETE) সফলভাবে সম্পন্ন হওয়ার পরে চলে। - সাধারণত এটি লগিং, অডিটিং, বা ডেটা সংক্রান্ত অন্যান্য কাজের জন্য ব্যবহৃত হয়।
- এই ট্রিগারটি ডেটাবেস অপারেশন (যেমন
- INSTEAD OF Trigger:
- এই ট্রিগারটি সাধারণত ভিউতে ব্যবহৃত হয় এবং এটি মূল
INSERT,UPDATE, বাDELETEঅপারেশনটি প্রতিস্থাপন করে। - এটি একটি বিশেষ ধরনের ট্রিগার, যা যখন ভিউতে পরিবর্তন করার প্রয়োজন হয়, তখন কাজ করে।
- এই ট্রিগারটি সাধারণত ভিউতে ব্যবহৃত হয় এবং এটি মূল
ট্রিগার ইভেন্ট
ট্রিগারের জন্য প্রধান ইভেন্টগুলো হলো:
- INSERT: একটি নতুন রেকর্ড যোগ করার সময় ট্রিগার কার্যকর হয়।
- UPDATE: একটি বিদ্যমান রেকর্ড পরিবর্তন করার সময় ট্রিগার কার্যকর হয়।
- DELETE: একটি রেকর্ড মুছে ফেললে ট্রিগার কার্যকর হয়।
PL/SQL Trigger উদাহরণ
১. BEFORE INSERT Trigger উদাহরণ
CREATE OR REPLACE TRIGGER check_salary_before_insert
BEFORE INSERT ON employees
FOR EACH ROW
BEGIN
-- Ensure that salary is greater than 1000 before insertion
IF :NEW.salary < 1000 THEN
RAISE_APPLICATION_ERROR(-20001, 'Salary must be greater than or equal to 1000');
END IF;
END;
এখানে:
- এই ট্রিগারটি BEFORE INSERT টাইপের।
- এটি employees টেবিলে নতুন রেকর্ড ইনসার্ট হওয়ার আগে চলে।
- ট্রিগারটি চেক করে, যদি salary এর মান 1000 এর কম হয়, তবে একটি RAISE_APPLICATION_ERROR ত্রুটি তৈরি করে।
২. AFTER UPDATE Trigger উদাহরণ
CREATE OR REPLACE TRIGGER log_salary_update
AFTER UPDATE ON employees
FOR EACH ROW
BEGIN
-- Log the old and new salary into a log table
INSERT INTO salary_log(employee_id, old_salary, new_salary, update_date)
VALUES (:OLD.employee_id, :OLD.salary, :NEW.salary, SYSDATE);
END;
এখানে:
- এই ট্রিগারটি AFTER UPDATE টাইপের।
- এটি employees টেবিলের কোনো রেকর্ড আপডেট হওয়ার পর চলে।
- ট্রিগারটি salary_log টেবিলে পুরানো এবং নতুন salary এবং আপডেটের তারিখ লগ করে।
৩. INSTEAD OF Trigger উদাহরণ
CREATE OR REPLACE TRIGGER update_employee_salary_instead_of
INSTEAD OF UPDATE ON employees
FOR EACH ROW
BEGIN
-- Custom logic for updating salary
IF :NEW.salary > 1000 THEN
UPDATE employees
SET salary = :NEW.salary
WHERE employee_id = :NEW.employee_id;
ELSE
RAISE_APPLICATION_ERROR(-20002, 'Salary cannot be less than 1000');
END IF;
END;
এখানে:
- এই ট্রিগারটি INSTEAD OF UPDATE টাইপের।
- এটি employees টেবিলে কোনো UPDATE অপারেশন ঘটলে, তা পরিবর্তন করে নিজের কাস্টম লজিক দিয়ে কাজ করে।
PL/SQL Trigger-এর System Variables
PL/SQL-এ ট্রিগার ব্যবহার করার সময়, আপনি বিভিন্ন system variables ব্যবহার করতে পারেন যা ডেটাবেসের বর্তমান স্টেট সম্পর্কে তথ্য দেয়।
প্রধান System Variables:
:NEW.column_name: নতুন রেকর্ডের মান (INSERT অথবা UPDATE এ ব্যবহৃত হয়)।:OLD.column_name: পুরানো রেকর্ডের মান (UPDATE অথবা DELETE এ ব্যবহৃত হয়)।:ROWCOUNT: প্রভাবিত সারির সংখ্যা (যেমন,INSERTবাDELETEএ)।
Example:
CREATE OR REPLACE TRIGGER track_salary_changes
AFTER UPDATE ON employees
FOR EACH ROW
BEGIN
-- Log changes only if salary has changed
IF :OLD.salary <> :NEW.salary THEN
INSERT INTO salary_changes_log(employee_id, old_salary, new_salary, change_date)
VALUES (:NEW.employee_id, :OLD.salary, :NEW.salary, SYSDATE);
END IF;
END;
এখানে:
:OLD.salaryপুরানো মান (যেটি আপডেট হওয়ার আগে ছিল) এবং:NEW.salaryনতুন মান।
Triggers-এর ব্যবহারিত সুনির্দিষ্ট ক্ষেত্রসমূহ
- ডেটাবেস ইন্টিগ্রিটি রক্ষা: যখন ডেটাবেসের কোনো পরিবর্তন ডেটার জন্য কিছু নির্দিষ্ট নিয়ম থাকে (যেমন, মান যাচাই), তখন ট্রিগার ব্যবহার করা হয়।
- অডিটিং এবং লগিং: গুরুত্বপূর্ণ ডেটা পরিবর্তন যেমন
INSERT,UPDATE,DELETEএর লগ রাখা। - স্বয়ংক্রিয় ব্যবস্থা: ডেটাবেসের মধ্যে নিয়মিত কাজ যেমন ডেটা পরিশোধন বা ক্যালকুলেশন স্বয়ংক্রিয় করা।
- ডেটা সংস্করণ নিয়ন্ত্রণ: কোনো রেকর্ড পরিবর্তন হলে তার পুরানো মান সংরক্ষণ করা।
PL/SQL Trigger-এর বিধিনিষেধ এবং সীমাবদ্ধতা
- ট্রিগারগুলি একটি সময় একাধিক বার কার্যকর হতে পারে যদি সংশ্লিষ্ট কার্যক্রমটি একাধিক রেকর্ডে প্রভাব ফেলতে থাকে।
- Recursive triggers: ট্রিগারগুলি যদি একে অপরকে কল করতে থাকে, তবে তা অসীম লুপ তৈরি করতে পারে। এজন্য Recursive triggers বন্ধ করতে কিছু সীমাবদ্ধতা দেওয়া হয়।
- Performance Impact: ট্রিগার ব্যবহারের কারণে ডেটাবেসের পারফরম্যান্সে প্রভাব পড়তে পারে, কারণ প্রতি
INSERT,UPDATE, বাDELETEঅপারেশনের পরে ট্রিগার চলবে।
সারাংশ:
- Triggers হল PL/SQL এর একটি শক্তিশালী বৈশিষ্ট্য যা ডেটাবেস অপারেশনগুলোর ওপর প্রতিক্রিয়া স্বয়ংক্রিয়ভাবে কার্যকর করার জন্য ব্যবহৃত হয়।
- PL/SQL-এ ট্রিগারের বিভিন্ন প্রকার রয়েছে যেমন BEFORE, AFTER, এবং INSTEAD OF যা বিভিন্ন কার্যক্রমের জন্য ব্যবহার করা হয়।
- Triggers ডেটাবেসের ইন্টিগ্রিটি বজায় রাখতে, অডিটিং করতে, এবং ডেটা প্রক্রিয়া স্বয়ংক্রিয় করতে ব্যবহৃত হয়।
Trigger ব্যবহার করার মাধ্যমে ডেটাবেসের কার্যক্রম আরো কন্ট্রোলযোগ্য এবং নিরাপদ করা সম্ভব।
Triggers হলো একটি বিশেষ ধরনের স্টোরড প্রোগ্রাম যা নির্দিষ্ট একটি ইভেন্ট (যেমন, ডেটাবেসের কোনো টেবিলের উপর ইনসার্ট, আপডেট বা ডিলিট অপারেশন) ঘটলে স্বয়ংক্রিয়ভাবে চালু হয়। এটি ডেটাবেসে ইভেন্ট-ড্রিভেন প্রোগ্রামিং এর একটি উদাহরণ, যেখানে একটি নির্দিষ্ট ইভেন্টের জন্য একটি অ্যাকশন (অথবা কাজ) সম্পাদিত হয়।
Triggers সাধারণত ডেটাবেস ইন্টিগ্রিটি, অটোমেশন, এবং অডিটিং এর জন্য ব্যবহৃত হয়। একটি Trigger টেবিলের মধ্যে অবাঞ্ছিত ডেটা পরিবর্তন এড়ানোর জন্য, ডেটা ভ্যালিডেশন করার জন্য এবং অডিটিং বা লগিং এর উদ্দেশ্যে ব্যবহার করা হতে পারে।
Triggers এর গঠন
PL/SQL তে একটি Trigger সাধারণত নিচের মতো গঠন করা হয়:
CREATE [OR REPLACE] TRIGGER trigger_name
{BEFORE | AFTER} {INSERT | UPDATE | DELETE}
ON table_name
[FOR EACH ROW]
DECLARE
-- Declare variables if needed
BEGIN
-- Trigger logic (actions to be performed when the event occurs)
END;
এখানে:
trigger_name: Trigger এর নাম।{BEFORE | AFTER}: Triggerটি কবে রান হবে তা নির্ধারণ করে (ইনসার্ট, আপডেট বা ডিলিটের আগে বা পরে)।{INSERT | UPDATE | DELETE}: কোন ইভেন্টটি trigger করবে।ON table_name: যে টেবিলের উপর Trigger প্রয়োগ হবে তা নির্দেশ করে।FOR EACH ROW: টেবিলের প্রতিটি রো-তে Trigger এক্সিকিউট হবে (এটা ROW-LEVEL Trigger এর জন্য)।
Triggers এর প্রকারভেদ
PL/SQL তে Trigger এর প্রধান তিনটি প্রকার রয়েছে:
- BEFORE Trigger:
- এই ধরনের Trigger কোনো
INSERT,UPDATE, বাDELETEঅপারেশনের আগে চলে। - এটি ডেটা ইনসার্ট করার আগে বা পরিবর্তন করার আগে ভ্যালিডেশন বা কাস্টম লজিক প্রয়োগ করার জন্য ব্যবহার করা হয়।
- এই ধরনের Trigger কোনো
- AFTER Trigger:
- এই ধরনের Trigger কোনো
INSERT,UPDATE, বাDELETEঅপারেশনের পরে চলে। - এটি ডেটা পরিবর্তনের পরে অডিটিং, লগিং, বা অন্য কোন অ্যাকশন সম্পাদন করার জন্য ব্যবহৃত হয়।
- এই ধরনের Trigger কোনো
- INSTEAD OF Trigger:
- এই ধরনের Trigger শুধুমাত্র
VIEWএর জন্য ব্যবহৃত হয় এবং একটিINSERT,UPDATE, বাDELETEঅপারেশনকে একটি ভিউতে প্রতিস্থাপন করে। - এটি মূলত ভিউতে ডেটা পরিবর্তন করার জন্য ব্যবহৃত হয়।
- এই ধরনের Trigger শুধুমাত্র
Triggers এর ব্যবহার কেন?
Triggers ব্যবহার করার কিছু গুরুত্বপূর্ণ কারণ এবং সুবিধা নিচে আলোচনা করা হলো:
1. ডেটাবেস ইন্টিগ্রিটি রক্ষা
- Triggers ডেটাবেসের ইন্টিগ্রিটি বজায় রাখতে সাহায্য করে। উদাহরণস্বরূপ, আপনি যদি একটি টেবিলে নতুন রেকর্ড ইনসার্ট করার আগে কিছু কন্ডিশন চেক করতে চান (যেমন, ডেটা ভ্যালিডেশন), তাহলে
BEFORE INSERTTrigger ব্যবহার করা যেতে পারে।
2. অটোমেশন
- Triggers আপনার ডেটাবেস অপারেশনগুলোকে অটোমেট করতে সাহায্য করে। এর মাধ্যমে আপনি একটি নির্দিষ্ট অপারেশন ঘটলে তা স্বয়ংক্রিয়ভাবে অন্য কিছু কাজ সম্পাদন করতে পারবেন। যেমন, আপনি যদি একটি টেবিলে ইনসার্ট হওয়া নতুন ডেটার ওপর ভিত্তি করে অন্য একটি টেবিল আপডেট করতে চান, তাহলে
AFTER INSERTTrigger ব্যবহার করতে পারেন।
3. অডিটিং এবং লগিং
- Triggers খুবই কার্যকর ডেটাবেসের কার্যক্রম ট্র্যাক করার জন্য। আপনি একটি
BEFORE UPDATETrigger ব্যবহার করে যে সমস্ত ডেটা পরিবর্তন হয়েছে তা লগে সংরক্ষণ করতে পারেন। এটি বিশেষ করে নিরাপত্তা বা অডিটিং এর ক্ষেত্রে খুবই গুরুত্বপূর্ণ।
4. ডেটা সিঙ্ক্রোনাইজেশন
- একাধিক টেবিল বা ডেটাবেসের মধ্যে ডেটা সিঙ্ক্রোনাইজেশন করতে Triggers ব্যবহার করা যেতে পারে। উদাহরণস্বরূপ, একটি টেবিলের ডেটা অন্য একটি টেবিল বা লজিকাল ভিউতে আপডেট করার জন্য
AFTER INSERTTrigger ব্যবহার করা যেতে পারে।
5. রিপোর্টিং এবং নোটিফিকেশন
- Triggers ব্যবহার করে আপনি যখন কোনো নির্দিষ্ট ইভেন্ট ঘটে তখন ব্যবহারকারী বা অ্যাডমিনকে নোটিফাই করতে পারেন। যেমন, যখন কোনো গুরুত্বপূর্ণ ডেটা আপডেট হয় তখন একটি ইমেইল পাঠানো বা লগ ইন করা।
6. অথেনটিকেশন এবং ভ্যালিডেশন
- Trigger ব্যবহার করে আপনি ডেটার উপর আরো শক্তিশালী ভ্যালিডেশন আরোপ করতে পারেন। উদাহরণস্বরূপ, আপনি একটি
BEFORE INSERTTrigger ব্যবহার করে নিশ্চিত করতে পারেন যে শুধুমাত্র সঠিক ফরম্যাটে ডেটা ইনসার্ট করা হচ্ছে।
Trigger এর উদাহরণ
BEFORE INSERT Trigger উদাহরণ:
CREATE OR REPLACE TRIGGER validate_employee_insert
BEFORE INSERT ON employees
FOR EACH ROW
BEGIN
IF :new.salary < 3000 THEN
RAISE_APPLICATION_ERROR(-20001, 'Salary must be greater than 3000.');
END IF;
END;
এখানে, validate_employee_insert Trigger টেবিলের মধ্যে নতুন ইনসার্ট হওয়া রেকর্ডের salary ফিল্ড চেক করে। যদি salary 3000 এর কম হয়, তাহলে এটি একটি ত্রুটি তৈরি করবে।
AFTER UPDATE Trigger উদাহরণ:
CREATE OR REPLACE TRIGGER log_employee_update
AFTER UPDATE ON employees
FOR EACH ROW
BEGIN
INSERT INTO employee_log (employee_id, action, action_date)
VALUES (:old.employee_id, 'Updated', SYSDATE);
END;
এখানে, log_employee_update Triggerটি টেবিলের একটি রেকর্ড আপডেট হওয়ার পর সেটির একটি লগ রেকর্ড তৈরি করে।
INSTEAD OF Trigger উদাহরণ (View এর জন্য):
CREATE OR REPLACE TRIGGER update_employee_salary
INSTEAD OF UPDATE ON employee_view
FOR EACH ROW
BEGIN
UPDATE employees
SET salary = :new.salary
WHERE employee_id = :old.employee_id;
END;
এখানে, employee_view ভিউতে যখন UPDATE অপারেশন ঘটে, তখন এটি মূল employees টেবিলকে আপডেট করবে।
Triggers এর সুবিধা এবং সীমাবদ্ধতা
সুবিধা:
- ডেটা সুরক্ষা: Trigger ব্যবহার করে আপনি ডেটাবেসের সঠিকতা এবং সুরক্ষা বজায় রাখতে পারেন।
- অটোমেশন: অনেক ধরনের ডেটাবেস কার্যক্রমকে অটোমেট করা যায়।
- একমাত্রিক স্থানে পরিবর্তন: একটি Trigger একাধিক টেবিল বা ডেটাবেসের মধ্যে পরিবর্তনগুলি সমন্বয় করতে সাহায্য করতে পারে।
সীমাবদ্ধতা:
- পারফরম্যান্স সমস্যা: অধিক পরিমাণ Trigger ব্যবহার করলে সিস্টেমের পারফরম্যান্স ক্ষতিগ্রস্ত হতে পারে, কারণ Trigger প্রতিটি সংশোধন ইভেন্টের জন্য এক্সিকিউট হতে হয়।
- নির্দিষ্ট ডিবাগিং সমস্যাগুলি: Trigger গুলি যদি ভুলভাবে কাজ করে তবে তা ডিবাগ করা কঠিন হতে পারে, কারণ তারা অটোমেটিক্যালি চলে এবং ত্রুটিগুলি আড়াল করতে পারে।
Conclusion:
Triggers ডেটাবেসের মধ্যে ইভেন্ট-ড্রিভেন প্রোগ্রামিং সিস্টেম তৈরির জন্য অত্যন্ত কার্যকরী একটি টুল। এটি ডেটাবেসের কার্যক্রম স্বয়ংক্রিয় করতে, ডেটা ইন্টিগ্রিটি নিশ্চিত করতে এবং ডেটাবেস সিকিউরিটি ও অডিটিং সুবিধা প্রদান করতে সাহায্য করে। তবে, অতিরিক্ত ব্যবহার বা ভুল কনফিগারেশন পারফরম্যান্স সমস্যার সৃষ্টি করতে পারে, তাই এটি বুঝে এবং প্রয়োজনে ব্যবহৃত হওয়া উচিত।
Triggers হল PL/SQL কোডের ব্লক যা বিশেষ কিছু ইভেন্ট বা পরিবর্তনের জন্য স্বয়ংক্রিয়ভাবে রান হয়। সাধারণত, Triggers ডেটাবেসে ডেটা ম্যানিপুলেশন (INSERT, UPDATE, DELETE) ঘটানোর আগে বা পরে রান হয়, এবং এগুলি ব্যবহৃত হয় ডেটাবেসের স্বয়ংক্রিয় কাজ বা ব্যবহারকারীর ক্রিয়ার প্রভাব সঠিকভাবে পরিচালনা করতে।
BEFORE এবং AFTER triggers দুটি প্রধান ধরনের trigger, যা নির্দিষ্ট কাজ করার জন্য ব্যবহৃত হয়।
BEFORE Trigger
BEFORE Trigger হল একটি trigger যা কোনো ডেটাবেস অপারেশন (INSERT, UPDATE, DELETE) সম্পাদন হওয়ার আগে কার্যকর হয়। যখন আপনি একটি BEFORE trigger ব্যবহার করেন, তখন আপনি তথ্য আপডেট বা পরিবর্তন করার আগে কিছু নির্দিষ্ট কোড কার্যকর করতে পারেন।
এটি সাধারণত ডেটা ভ্যালিডেশন বা অপারেশন থেকে পূর্বের অবস্থা চেক করা এর জন্য ব্যবহৃত হয়।
BEFORE Trigger ব্যবহার করা হয় যখন:
- একটি INSERT বা UPDATE করার আগে ডেটা যাচাই করতে চান।
- একটি ডেটার উপর প্রক্রিয়া চালানোর আগে কিছু কাস্টম লজিক প্রয়োগ করতে চান।
- ডেটা ইনপুট বা আপডেট করার আগেই নিরাপত্তা যাচাই করতে চান।
সিনট্যাক্স:
CREATE OR REPLACE TRIGGER before_trigger_example
BEFORE INSERT ON employees
FOR EACH ROW
BEGIN
-- Code to be executed before insert
:NEW.hire_date := SYSDATE; -- Automatically set hire_date to current date
END;
উদাহরণ:
ধরা যাক, একটি employees টেবিল আছে, যেখানে আপনি চান, যখন কেউ নতুন কর্মচারী অ্যাড করবে, তখন তার hire_date স্বয়ংক্রিয়ভাবে বর্তমান তারিখে সেট হোক।
CREATE OR REPLACE TRIGGER before_insert_employee
BEFORE INSERT ON employees
FOR EACH ROW
BEGIN
:NEW.hire_date := SYSDATE;
END;
এখানে, BEFORE INSERT trigger employees টেবিলে নতুন রেকর্ড ইনসার্ট করার আগে hire_date কলামটি বর্তমান তারিখে সেট করবে।
AFTER Trigger
AFTER Trigger হল একটি trigger যা একটি ডেটাবেস অপারেশন (INSERT, UPDATE, DELETE) সম্পন্ন হওয়ার পরে কার্যকর হয়। এটি সাধারণত ডেটাবেস অপারেশন শেষে কিছু কর্মকাণ্ড সম্পাদন করার জন্য ব্যবহৃত হয়।
AFTER Trigger ব্যবহার করে আপনি ডেটা আপডেট হওয়ার পরে কোনও লগ তৈরি করতে পারেন, বা পরে অন্য একটি টেবিল আপডেট বা ইনসার্ট করতে পারেন।
AFTER Trigger ব্যবহার করা হয় যখন:
- INSERT, UPDATE, বা DELETE অপারেশন শেষ হওয়ার পরে কিছু পরিবর্তন বা অডিট করতে চান।
- ডেটা পরিবর্তনের পরে কিছু কাজ করতে চান যেমন লগ ইনসার্ট করা।
- ডেটাবেসে অটোমেটিক বা সিরিয়াল অপারেশন সম্পাদন করতে চান।
সিনট্যাক্স:
CREATE OR REPLACE TRIGGER after_trigger_example
AFTER INSERT ON employees
FOR EACH ROW
BEGIN
-- Code to be executed after insert
INSERT INTO employee_audit_log (employee_id, action, action_date)
VALUES (:NEW.employee_id, 'INSERT', SYSDATE);
END;
উদাহরণ:
ধরা যাক, আপনি চান যে, যখনই কেউ employees টেবিলে একটি নতুন রেকর্ড ইনসার্ট করবে, তখন সেই পরিবর্তনের একটি লগ তৈরি হোক employee_audit_log টেবিলে।
CREATE OR REPLACE TRIGGER after_insert_employee
AFTER INSERT ON employees
FOR EACH ROW
BEGIN
INSERT INTO employee_audit_log (employee_id, action, action_date)
VALUES (:NEW.employee_id, 'INSERT', SYSDATE);
END;
এখানে, AFTER INSERT trigger employees টেবিলে নতুন রেকর্ড ইনসার্ট করার পর employee_audit_log টেবিলে একটি লগ এন্ট্রি তৈরি করবে।
BEFORE এবং AFTER Triggers এর মধ্যে পার্থক্য:
| Feature | BEFORE Trigger | AFTER Trigger |
|---|---|---|
| Execution Timing | The trigger executes before the database operation. | The trigger executes after the database operation. |
| Use Case | Used for data validation, modifying input before it's saved. | Used for logging, auditing, or cascading operations after a change. |
| Common Operations | Validating data before INSERT or UPDATE. | Inserting logs or triggering subsequent actions after INSERT or DELETE. |
| Access to Data | Can modify data using :NEW values. | Can only use :NEW values after the change has been applied. |
| Example | Setting a default value before INSERT (e.g., hire_date). | Auditing changes after an INSERT operation. |
BEFORE এবং AFTER Triggers এর ব্যবহারিক উদাহরণ:
BEFORE Trigger Example:
- আপনি চাইলে BEFORE trigger ব্যবহার করে ইনপুট ডেটার মান যাচাই করতে পারেন, যেমন অ্যাকাউন্ট নম্বরের ধরন বা দামটির সীমা।
CREATE OR REPLACE TRIGGER before_update_price BEFORE UPDATE ON products FOR EACH ROW BEGIN IF :NEW.price < 0 THEN RAISE_APPLICATION_ERROR(-20001, 'Price cannot be negative'); END IF; END;AFTER Trigger Example:
- AFTER trigger ব্যবহার করে আপনি লগ ইনসার্ট করতে পারেন যা ইভেন্টের পরবর্তী কার্যক্রম হিসেবে কাজ করে।
CREATE OR REPLACE TRIGGER after_delete_employee AFTER DELETE ON employees FOR EACH ROW BEGIN INSERT INTO employee_audit_log (employee_id, action, action_date) VALUES (:OLD.employee_id, 'DELETE', SYSDATE); END;
এখানে, AFTER DELETE trigger যখনই একটি employee টেবিলের রেকর্ড মুছে ফেলা হবে, তখন সেই কর্মচারীর তথ্য employee_audit_log টেবিলে একটি লগ হিসেবে ইনসার্ট হবে।
উপসংহার:
BEFORE এবং AFTER triggers বিভিন্ন পরিস্থিতিতে ডেটাবেসে বিভিন্ন ধরনের কাজ করার জন্য ব্যবহৃত হয়। BEFORE triggers সাধারণত ডেটা ম্যানিপুলেশন বা ইনপুট যাচাই করার জন্য, এবং AFTER triggers সাধারণত লগিং, অডিটিং, এবং পরবর্তী অ্যাকশন নেওয়ার জন্য ব্যবহৃত হয়।
Triggers হলো PL/SQL এর একটি গুরুত্বপূর্ণ ফিচার যা একটি নির্দিষ্ট ইভেন্ট বা ডাটাবেস অপারেশন (যেমন INSERT, UPDATE, DELETE) ঘটলে স্বয়ংক্রিয়ভাবে চলতে থাকে। Triggers ব্যবহার করে ডাটাবেসের ডেটা অবস্থা পরিবর্তন বা অন্যান্য কার্যকলাপের উপর নজর রাখা যায়। Triggers প্রধানত দুটি প্রকারে ভাগ করা হয়: Row Level Triggers এবং Statement Level Triggers।
১. Row Level Trigger
Row Level Trigger তখন কার্যকর হয় যখন প্রতিটি রেকর্ড (row) উপর একটি নির্দিষ্ট অপারেশন (যেমন INSERT, UPDATE, DELETE) ঘটানো হয়। প্রতিটি affected রেকর্ডের জন্য আলাদাভাবে trigger চালানো হয়।
উদাহরণ:
ধরা যাক, আপনি একটি employees টেবিলের জন্য একটি row-level trigger তৈরি করতে চান, যা যখন salary কলামে কোনো পরিবর্তন হয় তখন একটি audit_log টেবিলে লগ রাখবে।
CREATE OR REPLACE TRIGGER employee_salary_update
AFTER UPDATE OF salary ON employees
FOR EACH ROW
BEGIN
-- Log the update to audit_log table
INSERT INTO audit_log (employee_id, old_salary, new_salary, update_time)
VALUES (:OLD.employee_id, :OLD.salary, :NEW.salary, SYSDATE);
END;
এখানে,
AFTER UPDATE OF salary ON employees— যখনemployeesটেবিলেরsalaryকলাম আপডেট হয়।FOR EACH ROW— প্রতিটি affected row এর জন্য trigger কার্যকর হবে।:OLD.salary— পুরনো salary (যেহেতু এটিUPDATEঅপারেশন, তাই আগের মান পাওয়া যাবে)।:NEW.salary— নতুন salary (যেহেতু এটিUPDATEঅপারেশন, তাই নতুন মান পাওয়া যাবে)।
এই triggerটি প্রতিটি row আপডেট হওয়ার পরে চালানো হবে এবং সংশ্লিষ্ট তথ্য audit_log টেবিলে ইনসার্ট হবে।
Row Level Trigger এর সুবিধা:
- প্রতিটি রেকর্ডের জন্য পৃথক কাজ: এটি যখন প্রতিটি affected row-এ আলাদাভাবে কাজ করতে হয়, যেমন বিশেষভাবে
UPDATEবাDELETEঅপারেশনগুলির জন্য। - বিশেষ প্রয়োজনে কাজ: যখন আপনাকে নির্দিষ্ট ডেটা, যেমন পুরনো এবং নতুন মানের মধ্যে পার্থক্য ট্র্যাক করতে হয়।
২. Statement Level Trigger
Statement Level Trigger একাধিক রেকর্ডের উপর একই অপারেশন করার পরিবর্তে, একটি SQL স্টেটমেন্টের সম্পূর্ণ প্রক্রিয়ার পরপরই কার্যকর হয়। এই trigger শুধুমাত্র একবার চালানো হয়, যদি পুরো statement (যেমন INSERT, UPDATE, DELETE) সফল হয়, তা নির্বিশেষে affected row এর সংখ্যা কেমনই হোক না কেন।
উদাহরণ:
ধরা যাক, আপনি একটি employees টেবিলের জন্য একটি statement-level trigger তৈরি করতে চান, যা যখন একটি INSERT অপারেশন হবে, তখন পুরো টেবিলের রেকর্ডের সংখ্যা একটি লগ টেবিলে সংরক্ষণ করবে।
CREATE OR REPLACE TRIGGER employee_insert_count
AFTER INSERT ON employees
BEGIN
-- Log the total number of employees after each insert
INSERT INTO employee_count_log (employee_count, log_time)
VALUES ((SELECT COUNT(*) FROM employees), SYSDATE);
END;
এখানে,
AFTER INSERT ON employees— যখনemployeesটেবিলে একটি নতুন রেকর্ড ইনসার্ট হবে।INSERT INTO employee_count_log— এটিemployee_count_logটেবিলে সমস্ত কর্মচারীর সংখ্যা একটি লগ হিসেবে সঞ্চিত করবে।
এটি কেবলমাত্র একটি বার কার্যকর হবে, প্রতিটি INSERT অপারেশনের জন্য, এবং affected row এর সংখ্যা নির্বিশেষে।
Statement Level Trigger এর সুবিধা:
- একই অপারেশনের জন্য একাধিক রেকর্ডের পরিবর্তে একবার কাজ: যখন একাধিক affected rows না হলেও, একটি বার কাজ করতে হয় (যেমন লগিং বা মোট সঠিক সংখ্যা নির্ণয়)।
- দ্রুত কর্ম: প্রতিটি affected row এর পরিবর্তে একবার কাজ করার ফলে কার্যকারিতা সাধারণত ভালো হয়।
Row Level এবং Statement Level Trigger এর মধ্যে পার্থক্য
| বৈশিষ্ট্য | Row Level Trigger | Statement Level Trigger |
|---|---|---|
| কার্যকর হওয়ার সময় | প্রতিটি affected row এর জন্য আলাদাভাবে | পুরো SQL স্টেটমেন্টের একবার পর কার্যকর |
| ব্যবহার | একক রেকর্ডের উপর কাজ করতে ব্যবহৃত | একাধিক রেকর্ড বা একটি সাধারণ কাজের জন্য ব্যবহৃত |
| কোড উদাহরণ | FOR EACH ROW | কোন FOR EACH ROW ক্লজ নেই |
| প্রত্যাশিত ফলাফল | প্রতিটি affected row এর জন্য trigger চলবে | একবার পুরো SQL statement সফল হলে trigger চলবে |
| পারফরম্যান্স | বেশি ব্যয়বহুল হতে পারে, কারণ প্রতিটি row এর জন্য trigger চলে | সাধারনভাবে দ্রুত, কারণ একবার কাজ করা হয় |
উদাহরণগুলি
Row Level Trigger উদাহরণ:
যখন একটি DELETE অপারেশন হয়, তখন affected row গুলির জন্য একটি লোগ তৈরি করতে Row Level Trigger ব্যবহার করা যেতে পারে।
CREATE OR REPLACE TRIGGER delete_employee_log
AFTER DELETE ON employees
FOR EACH ROW
BEGIN
-- Log deleted employee data into audit log
INSERT INTO deleted_employee_log (employee_id, employee_name, delete_time)
VALUES (:OLD.employee_id, :OLD.employee_name, SYSDATE);
END;
এখানে, প্রতিটি affected row এর জন্য delete_employee_log trigger কার্যকর হবে এবং deleted employee এর তথ্য লগে সংরক্ষিত হবে।
Statement Level Trigger উদাহরণ:
একটি UPDATE অপারেশন পর, পুরো টেবিলের সংখ্যার একটি লগ তৈরি করতে Statement Level Trigger ব্যবহার করা যেতে পারে।
CREATE OR REPLACE TRIGGER update_employee_log
AFTER UPDATE ON employees
BEGIN
-- Log the total number of employees after every update
INSERT INTO update_log (log_time, employee_count)
VALUES (SYSDATE, (SELECT COUNT(*) FROM employees));
END;
এটি UPDATE অপারেশন পর পুরো টেবিলের মোট কর্মচারীর সংখ্যা লোগ করবে।
উপসংহার
Row Level Triggers এবং Statement Level Triggers এর মধ্যে প্রধান পার্থক্য হল যে row level trigger প্রতিটি affected row এর জন্য আলাদাভাবে কাজ করে, whereas statement level trigger সম্পূর্ণ SQL স্টেটমেন্টের জন্য একবার কাজ করে। কোনটি ব্যবহার করবেন তা আপনার ব্যবহারের পরিস্থিতির উপর নির্ভর করবে। Row Level Trigger ব্যবহার করা হয় যখন আপনি প্রতিটি row এর উপর বিস্তারিত কার্যকলাপ চান, এবং Statement Level Trigger ব্যবহার করা হয় যখন একই ধরনের কাজ একবার সম্পাদন করতে হবে।
INSTEAD OF Triggers একটি বিশেষ ধরনের trigger যা VIEW তে INSERT, UPDATE, অথবা DELETE অপারেশন করার সময় কার্যকর হয়। এই trigger এর মাধ্যমে আপনি VIEW তে কোনো ডেটা পরিবর্তন করার চেষ্টা করলে, ঐ পরিবর্তনটি আসলে মূল টেবিল বা ডেটাবেস অবজেক্ট এ করা হয়। এটি মূলত VIEW গুলোর ক্ষেত্রে ব্যবহার করা হয়, কারণ VIEW তে সরাসরি INSERT, UPDATE, বা DELETE করা সম্ভব নয়। INSTEAD OF Trigger এর মাধ্যমে এই অপারেশনগুলো মূল টেবিল বা অন্য কোনো ডেটাবেস অবজেক্টে পরিবর্তন করতে ব্যবহৃত হয়।
এই ধরনের trigger সাধারণত তখন ব্যবহৃত হয় যখন একটি কমপ্লেক্স ভিউ বা ডেটাবেস অবজেক্ট এর উপর INSERT, UPDATE, বা DELETE করতে হবে, কিন্তু সেই ভিউতে সরাসরি ডেটা পরিবর্তন সম্ভব নয়।
INSTEAD OF Trigger এর গঠন:
CREATE OR REPLACE TRIGGER trigger_name
INSTEAD OF {INSERT | UPDATE | DELETE}
ON view_name
FOR EACH ROW
BEGIN
-- Trigger body
-- Perform operations on the underlying base tables
END;
এখানে:
trigger_name: Trigger এর নাম।{INSERT | UPDATE | DELETE}: আপনি কোন অপারেশনটি করতে চান (এটিINSERT,UPDATE, বাDELETEহতে পারে)।view_name: যেইVIEWতে আপনি এই trigger প্রয়োগ করতে চান।FOR EACH ROW: এই triggerটি প্রতিটি affected row এর জন্য কাজ করবে।
INSTEAD OF Trigger এর ব্যবহার:
INSTEAD OF Triggers বিশেষভাবে VIEW গুলোর জন্য ব্যবহৃত হয়, কারণ VIEW তে ডেটা পরিবর্তন করার জন্য এক্সিকিউটেবল SQL স্টেটমেন্ট নেই। INSTEAD OF trigger তৈরি করলে, আপনি VIEW তে পরিবর্তন করতে পারবেন এবং সেই পরিবর্তন আসলে underlying টেবিলের উপর কার্যকর হবে।
INSTEAD OF Trigger এর উদাহরণ:
উদাহরণ ১: INSERT Operation এর জন্য INSTEAD OF Trigger
ধরা যাক, আপনার একটি employee_view নামক VIEW আছে, যেখানে employees এবং departments টেবিলের কিছু তথ্য সংযুক্ত করা হয়েছে। আপনি employee_view এ INSERT করতে চান, তবে এটি আসলে employees টেবিলের উপর INSERT করবে।
CREATE OR REPLACE TRIGGER employee_view_insert
INSTEAD OF INSERT ON employee_view
FOR EACH ROW
BEGIN
-- Insert the data into the employees table
INSERT INTO employees (employee_id, employee_name, department_id)
VALUES (:NEW.employee_id, :NEW.employee_name, :NEW.department_id);
END;
এখানে,
employee_view_inserttrigger টিemployee_viewএINSERTহওয়া ডেটাemployeesটেবিলের মধ্যে ইনসার্ট করে।:NEW.employee_id,:NEW.employee_name, এবং:NEW.department_idভিউ থেকে নেওয়া নতুন মান।
ব্যাখ্যা:
এই trigger এর মাধ্যমে, যখন আপনি employee_view তে নতুন employee যুক্ত করতে যাবেন, তখন ডেটা আসলে employees টেবিলের উপর ইনসার্ট হবে। VIEW তে INSERT করার অনুমতি না থাকলেও, INSTEAD OF Trigger এর মাধ্যমে আপনি ঐ পরিবর্তনটি করতে পারবেন।
উদাহরণ ২: UPDATE Operation এর জন্য INSTEAD OF Trigger
ধরা যাক, আপনি একটি employee_view নামক VIEW এ UPDATE করতে চান, কিন্তু ঐ ভিউতে সরাসরি আপডেট করা যাবে না। আপনি একটি INSTEAD OF trigger তৈরি করতে পারেন যা underlying employees টেবিলে আপডেট করবে।
CREATE OR REPLACE TRIGGER employee_view_update
INSTEAD OF UPDATE ON employee_view
FOR EACH ROW
BEGIN
-- Update the corresponding row in the employees table
UPDATE employees
SET employee_name = :NEW.employee_name,
department_id = :NEW.department_id
WHERE employee_id = :OLD.employee_id;
END;
এখানে,
employee_view_updatetrigger টিemployee_viewএUPDATEহওয়া ডেটাemployeesটেবিলের মধ্যে আপডেট করে।:OLD.employee_idপুরনোemployee_id, এবং:NEW.employee_name,:NEW.department_idনতুন মান।
ব্যাখ্যা:
যখন আপনি employee_view তে কোনো UPDATE করবেন, তখন তা আসলে employees টেবিলের উপর UPDATE করবে। INSTEAD OF trigger ব্যবহার করার মাধ্যমে আপনি VIEW এর মাধ্যমে underlying টেবিলগুলোতে পরিবর্তন আনতে পারেন।
উদাহরণ ৩: DELETE Operation এর জন্য INSTEAD OF Trigger
ধরা যাক, আপনার employee_view ভিউতে আপনি DELETE অপারেশন করতে চান, কিন্তু সরাসরি DELETE করা যাবে না। আপনি INSTEAD OF DELETE trigger ব্যবহার করতে পারেন যা underlying টেবিল থেকে ডেটা মুছে ফেলবে।
CREATE OR REPLACE TRIGGER employee_view_delete
INSTEAD OF DELETE ON employee_view
FOR EACH ROW
BEGIN
-- Delete the corresponding row from the employees table
DELETE FROM employees
WHERE employee_id = :OLD.employee_id;
END;
এখানে,
employee_view_deletetrigger টিemployee_viewতেDELETEহওয়া ডেটাemployeesটেবিল থেকে মুছে ফেলবে।:OLD.employee_idহল পুরনোemployee_idযার উপরDELETEঅপারেশন চলছে।
ব্যাখ্যা:
এটি যখন employee_view তে DELETE অপারেশন হবে, তখন underlying employees টেবিল থেকে সংশ্লিষ্ট রেকর্ডটি মুছে ফেলা হবে।
INSTEAD OF Trigger এর সুবিধা
- Complex Views-এ ডেটা আপডেট: যখন
VIEWএর মাধ্যমে ডেটা আপডেট বা ইনসার্ট করার চেষ্টা করা হয় এবং সেই ভিউটির উপর সরাসরি পরিবর্তন করা সম্ভব নয়, তখনINSTEAD OF Triggerব্যবহার করেVIEWএর মাধ্যমে underlying টেবিল বা ডেটাবেস অবজেক্টে পরিবর্তন করতে পারেন। - ভিউগুলোর মধ্যে অটোমেশন: আপনি ভিউগুলোর মধ্যে অটোমেশন এবং ডেটা সুরক্ষা নিশ্চিত করতে পারবেন, যেমন বিভিন্ন টেবিলের ডেটা একত্রিত করে একটি সাধারণ ভিউ তৈরি করা হলেও, তার জন্য ইনসার্ট বা আপডেট করা হবে শুধু একটিমাত্র টেবিলের জন্য।
- ডেটাবেস লজিক লুকানো: ভিউয়ের মাধ্যমে আপনি আপনার ডেটাবেস লজিক লুকিয়ে রাখতে পারেন, ফলে ব্যবহারকারী শুধুমাত্র ভিউটি ব্যবহার করবে এবং underlying টেবিলগুলোর বিষয়ে চিন্তা করতে হবে না।
উপসংহার
INSTEAD OF Trigger VIEW এর সাথে সংযুক্ত অপারেশনগুলিকে মূল টেবিলের মধ্যে বাস্তবায়িত করার জন্য একটি শক্তিশালী পদ্ধতি। এটি ডেটাবেস লজিকের যথাযথ ব্যবস্থাপনা নিশ্চিত করে এবং ভিউগুলোর মাধ্যমে ডেটাবেসের সাথে ইন্টারঅ্যাকশন সহজ করে তোলে। INSTEAD OF triggers অত্যন্ত কার্যকর যখন আপনার কাজের জন্য কমপ্লেক্স ভিউ দরকার হয় এবং ঐ ভিউগুলোর মাধ্যমে ডেটা আপডেট বা মুছে ফেলতে হয়।
Read more